<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>chat</title>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script src="http://47.106.66.89:8080/js/vue.min.js"></script>
    <!-- ele 的引入放在vue下面-->
    <link href="http://47.106.66.89:8080/js/ele-2.15.7/theme-chalk/index.css" rel="stylesheet">
    <script src="http://47.106.66.89:8080/js/ele-2.15.7/index.js"></script>
    <script src="http://47.106.66.89:8080/js/axios.min.js"></script>
</head>
<body>

<div id="app" class="chat-app">
    <!-- Same template content as before -->
    <div class="chat-container">
        <nav>
            <!-- 导航栏左侧 logo -->
            <div class="logo">Logo</div>
            <!-- 导航栏右侧登录注册按钮 -->
            <div class="auth-buttons" v-if="!myinfo">
                <button @click="showAuthModal = true">登录</button>
                <button @click="showAuthModal = true">注册</button>
            </div>
            <div class="auth-buttons" v-else=>
                欢迎:{{myinfo.name}}
                <button @click="logout">退出登录</button>
            </div>
        </nav>

        <!-- 登录注册弹窗 -->
        <div v-if="showAuthModal" class="modal-overlay" @click.self="showAuthModal = false">
            <div class="modal-content">
                <!-- 关闭按钮 -->
                <button class="close-button" @click="showAuthModal = false">&times;</button>

                <!-- 登录/注册选项卡 -->
                <div class="tabs">
                    <button
                            class="tab-button"
                            :class="{ active: activeTab === 'login' }"
                            @click="activeTab = 'login'"
                    >
                        登录
                    </button>
                    <button
                            class="tab-button"
                            :class="{ active: activeTab === 'register' }"
                            @click="activeTab = 'register'"
                    >
                        注册
                    </button>
                </div>

                <!-- 登录表单 -->
                <div v-if="activeTab === 'login'" class="auth-form">
                    <div class="form-group">
                        <label for="login-username">用户名</label>
                        <input
                                id="login-username"
                                type="text"
                                v-model="loginForm.username"
                                placeholder="请输入用户名"
                        >
                    </div>
                    <div class="form-group">
                        <label for="login-password">密码</label>
                        <input
                                id="login-password"
                                type="password"
                                v-model="loginForm.password"
                                placeholder="请输入密码"
                        >
                    </div>
                    <button class="submit-button" @click="handleLogin">登录</button>
                </div>

                <!-- 注册表单 -->
                <div v-if="activeTab === 'register'" class="auth-form">
                    <div class="form-group">
                        <label for="register-username">用户名</label>
                        <input
                                id="register-username"
                                type="text"
                                v-model="registerForm.username"
                                placeholder="请输入用户名"
                        >
                    </div>
                    <div class="form-group">
                        <label for="register-email">邮箱</label>
                        <input
                                id="register-email"
                                type="email"
                                v-model="registerForm.email"
                                placeholder="请输入邮箱"
                        >
                    </div>
                    <div class="form-group">
                        <label for="register-password">密码</label>
                        <input
                                id="register-password"
                                type="password"
                                v-model="registerForm.password"
                                placeholder="请输入密码"
                        >
                    </div>
                    <div class="form-group">
                        <label for="register-confirm-password">确认密码</label>
                        <input
                                id="register-confirm-password"
                                type="password"
                                v-model="registerForm.confirmPassword"
                                placeholder="请再次输入密码"
                        >
                    </div>
                    <button class="submit-button" @click="handleRegister">注册</button>
                </div>
            </div>
        </div>

        <!-- Title Bar -->
        <div class="chat-header">
            <div class="avatar">
                <img src="https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/FileBizType.BIZ_BOT_ICON/default_bot_icon4.png?lk3s=50ccb0c5&x-expires=1749370506&x-signature=72DjbzS0%2BPWECQGo1J31o19muqg%3D" alt="AI Avatar">
            </div>
            <div class="title">
                <h2>AI 助手</h2>
                <span class="status">在线</span>
            </div>
            <div class="actions">
                <i class="el-icon-more"></i>
            </div>
        </div>

        <!-- Chat Content Area -->
        <div class="chat-content" ref="messagesContainer">
            <div
                    v-for="(message, index) in messages"
                    :key="index"
                    :class="['message', message.type == '0' ? 'ai' : 'user']"
            >
                <div class="avatar" v-if="message.type == '0'">
                    <img src="https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/FileBizType.BIZ_BOT_ICON/default_bot_icon4.png?lk3s=50ccb0c5&x-expires=1749370506&x-signature=72DjbzS0%2BPWECQGo1J31o19muqg%3D" alt="AI Avatar">
                </div>
                <div class="bubble-container">
                    <div class="bubble">
                        <div class="content">{{ message.content }}</div>
                        <div class="time">{{ formatTime(message.time) }}</div>
                    </div>
                </div>
            </div>

            <!-- Loading Indicator -->
            <div v-if="loading" class="message ai">
                <div class="avatar">
                    <img src="https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/FileBizType.BIZ_BOT_ICON/default_bot_icon4.png?lk3s=50ccb0c5&x-expires=1749370506&x-signature=72DjbzS0%2BPWECQGo1J31o19muqg%3D" alt="AI Avatar">
                </div>
                <div class="bubble-container">
                    <div class="bubble">
                        <div class="loading-dots">
                            <span></span>
                            <span></span>
                            <span></span>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Input Area -->
        <div class="chat-input">
            <div class="input-tools">
                <i class="el-icon-picture"></i>
                <i class="el-icon-folder"></i>
                <i class="el-icon-video-camera"></i>
            </div>
            <el-input
                    v-model="inputMessage"
                    type="textarea"
                    :rows="3"
                    placeholder="输入消息..."
                    @keyup.enter.native="sendMessage"
                    :disabled="loading"
            ></el-input>
            <div class="input-actions">
                <el-button
                        type="primary"
                        @click="sendMessage"
                        :disabled="!inputMessage.trim() || loading"
                >
                    发送
                </el-button>
            </div>
        </div>
    </div>
</div>

<script>
    var v = new Vue({
        el: "#app",
        data: {
            inputMessage: '',
            messages: [],
            loading: false,
            eventSource: null,
            isStreaming: false, // 新增流式响应状态标志
            myinfo: {},

            showAuthModal: false,
            activeTab: 'login',
            loginForm: {
                username: '',
                password: ''
            },
            registerForm: {
                username: '',
                email: '',
                password: '',
                confirmPassword: ''
            }


        },

        created() {
            this.getMyinfo();
        },
        methods: {

            getMessage(){
                axios.get("chat/getMessage?uid=" + this.myinfo.id).then(res => {
                    if (res.data.code === 1) {
                        res.data.data.forEach(item => {
                            this.messages.push({
                                id:item.id,
                                uid:item.uid,
                                type: item.type,
                                content: item.content,
                                time: new Date(item.time)
                            })
                        });
                        this.messages.push({
                            id:'',
                            uid:'',
                            type: '0',
                            content: '你好！我是AI助手，有什么可以帮您的吗？',
                            time: new Date()
                        })
                    }
                })
            },

            getMyinfo() {
                axios.get("user/myinfo").then(res => {
                    if (res.data.code === 1) {
                        this.myinfo = res.data.data;
                        this.getMessage();
                    }
                })
            },
            sendMessage: function() {
                if (!this.inputMessage.trim() || this.loading) return;

                // 添加用户消息
                this.messages.push({
                    type: '1',
                    content: this.inputMessage,
                    time: new Date()
                });

                const userMessage = this.inputMessage;
                this.inputMessage = '';
                this.loading = true;
                this.isStreaming = true; // 开始流式响应
                this.scrollToBottom();

                try {
                    // 关闭之前的连接
                    if (this.eventSource) {
                        this.eventSource.close();
                    }

                    const eventSource = new EventSource(`/chat/stream?msg=${encodeURIComponent(userMessage)}`);
                    this.eventSource = eventSource;

                    var vm = this;
                    var aiResponse = '';

                    // 先创建AI消息容器
                    vm.messages.push({
                        type: '0',
                        content: '',
                        time: new Date(),
                        isMarkdown: true
                    });

                    eventSource.onmessage = function(event) {
                        try {
                            // 追加新内容
                            aiResponse += event.data;
                            vm.messages[vm.messages.length - 1].content = aiResponse;
                            vm.scrollToBottom();
                        } catch (error) {
                            console.error('Error processing message:', error);
                        }
                    };

                    eventSource.addEventListener('end', function() {
                        vm.finishStreaming(); // 专门的处理方法
                    });

                    eventSource.onerror = function(error) {
                        // 忽略正常关闭的错误
                        if (eventSource.readyState === EventSource.CLOSED) return;

                        console.error('EventSource error:', error);
                        vm.finishStreaming();
                    };

                } catch (error) {
                    console.error('Error:', error);
                    this.finishStreaming();
                }
            },

            // 新增方法：结束流式响应
            finishStreaming: function() {
                this.loading = false;
                this.isStreaming = false;
                if (this.eventSource) {
                    this.eventSource.close();
                }

                // 如果AI消息为空，则移除
                const lastMsg = this.messages[this.messages.length - 1];
                if (lastMsg.role === 'ai' && !lastMsg.content.trim()) {
                    this.messages.pop();
                }

                this.scrollToBottom();
            },

            scrollToBottom: function() {
                this.$nextTick(() => {
                    const container = this.$refs.messagesContainer;
                    if (container) {
                        container.scrollTop = container.scrollHeight;
                        // 确保滚动到底部
                        setTimeout(() => {
                            container.scrollTop = container.scrollHeight;
                        }, 50);
                    }
                });
            },

            formatTime: function(date) {
                return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
            },
            handleLogin(){
                axios.get("user/login", {
                    params: {
                        name: this.loginForm.username,
                        password: this.loginForm.password
                    }
                }).then(res => {
                    if (res.data.code === 1) {
                        this.$message(res.data.msg)
                        this.showAuthModal = false;
                        this.getMyinfo();
                    }else{
                        this.$alert(res.data.msg)
                    }
                })
            },
            handleRegister(){
                axios.get("user/reg", {
                    params: {
                        name: this.registerForm.username,
                        email: this.registerForm.email,
                        password: this.registerForm.password,
                        repassword: this.registerForm.confirmPassword
                    }
                }).then(res => {
                    if (res.data.code === 1) {
                        this.$message(res.data.msg)
                        this.showAuthModal = false;
                    }else{
                        this.$alert(res.data.msg)
                    }
                })
            },
            logout(){
                axios.get("user/logout").then(res => {
                    if (res.data.code === 1) {
                        this.$message(res.data.msg)
                        this.getMyinfo();
                    }
                })
            }
        },
        beforeDestroy: function() {
            if (this.eventSource) {
                this.eventSource.close();
            }
        }
    });
</script>


<style>

    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    /* 导航栏样式 */
    nav {
        display: flex;
        justify-content: space-between;
        align-items: center;
        /* 修改为浅色背景 */
        background-color: #f8f9fa;
        /* 修改文字颜色 */
        color: #333;
        padding: 1rem 2rem;
    }

    /* 导航栏左侧 logo 样式 */
    .logo {
        font-size: 1.5rem;
        font-weight: bold;
    }

    /* 导航栏中间链接列表样式 */
    .nav-links {
        display: flex;
        list-style: none;
    }

    /* 导航栏链接样式 */
    .nav-links li {
        margin: 0 1rem;
    }

    .nav-links li a {
        /* 修改链接文字颜色 */
        color: #333;
        text-decoration: none;
        transition: color 0.3s ease;
    }

    .nav-links li a:hover {
        /* 修改链接悬停颜色 */
        color: #0d6efd;
    }

    /* 导航栏右侧登录注册按钮样式 */
    .auth-buttons {
        display: flex;
    }

    .auth-buttons button {
        /* 修改按钮背景色 */
        background-color: #0d6efd;
        /* 修改按钮文字颜色 */
        color: white;
        border: none;
        border-radius: 4px;
        padding: 0.5rem 1rem;
        margin-left: 1rem;
        cursor: pointer;
        transition: background-color 0.3s ease;
    }

    .auth-buttons button:hover {
        /* 修改按钮悬停背景色 */
        background-color: #0b5ed7;
    }
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    }

    .chat-app {
        width: 100%;
        height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #f5f5f5;
        padding: 20px;
        box-sizing: border-box;
    }

    .chat-container {
        width: 100%;
        max-width: 800px;
        height: 90vh;
        background-color: white;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .chat-header {
        padding: 15px;
        border-bottom: 1px solid #eee;
        display: flex;
        align-items: center;
        flex-shrink: 0;
    }

    .avatar {
        margin-right: 10px;
        flex-shrink: 0;
    }

    .avatar img {
        width: 40px;
        height: 40px;
        border-radius: 50%;
    }

    .title {
        flex: 1;
    }

    .title h2 {
        margin: 0;
        font-size: 16px;
    }

    .status {
        color: #999;
        font-size: 12px;
        margin-left: 5px;
    }

    .actions {
        color: #999;
        cursor: pointer;
    }

    .chat-content {
        flex: 1;
        overflow-y: auto;
        padding: 15px;
        display: flex;
        flex-direction: column;
    }

    .message {
        display: flex;
        margin-bottom: 15px;
    }

    .message.user {
        justify-content: flex-end;
    }

    .message.ai {
        justify-content: flex-start;
    }

    .bubble-container {
        max-width: 70%;
    }

    .bubble {
        padding: 10px 15px;
        border-radius: 18px;
        position: relative;
    }

    .message.ai .bubble {
        background-color: #f0f0f0;
        margin-left: 10px;
    }

    .message.user .bubble {
        background-color: #409EFF;
        color: white;
        margin-right: 10px;
    }

    .time {
        font-size: 11px;
        color: #999;
        margin-top: 5px;
        text-align: right;
    }

    .message.user .time {
        color: rgba(255, 255, 255, 0.7);
    }

    .chat-input {
        border-top: 1px solid #eee;
        padding: 15px;
        flex-shrink: 0;
    }

    .input-tools {
        display: flex;
        gap: 15px;
        color: #999;
        margin-bottom: 10px;
    }

    .input-tools i {
        cursor: pointer;
    }

    .input-actions {
        display: flex;
        justify-content: flex-end;
        margin-top: 10px;
    }

    .loading-dots {
        display: inline-flex;
        align-items: center;
        height: 100%;
        padding: 12px 0;
    }

    .loading-dots span {
        display: inline-block;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background-color: #666;
        margin: 0 2px;
        animation: bounce 1.4s infinite ease-in-out both;
    }

    .loading-dots span:nth-child(1) {
        animation-delay: -0.32s;
    }

    .loading-dots span:nth-child(2) {
        animation-delay: -0.16s;
    }

    @keyframes bounce {
        0%, 80%, 100% {
            transform: scale(0);
        } 40% {
              transform: scale(1.0);
          }
    }

    /* 隐藏空的AI消息占位符 */
    .message.ai .content:empty {
        display: none;
    }

    /* 加载指示器样式 */
    .loading-indicator {
        text-align: center;
        padding: 10px;
        color: #999;
    }

    /* 弹窗样式 */
    .modal-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 1000;
    }

    .modal-content {
        background-color: white;
        padding: 30px;
        border-radius: 8px;
        width: 400px;
        max-width: 90%;
        position: relative;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    }

    .close-button {
        position: absolute;
        top: 10px;
        right: 10px;
        background: none;
        border: none;
        font-size: 24px;
        cursor: pointer;
        color: #666;
    }

    .close-button:hover {
        color: #333;
    }

    /* 选项卡样式 */
    .tabs {
        display: flex;
        margin-bottom: 20px;
        border-bottom: 1px solid #ddd;
    }

    .tab-button {
        flex: 1;
        padding: 10px;
        background: none;
        border: none;
        cursor: pointer;
        font-size: 16px;
        color: #666;
        border-bottom: 2px solid transparent;
    }

    .tab-button.active {
        color: #4CAF50;
        border-bottom: 2px solid #4CAF50;
        font-weight: bold;
    }

    /* 表单样式 */
    .auth-form {
        display: flex;
        flex-direction: column;
        gap: 15px;
    }

    .form-group {
        display: flex;
        flex-direction: column;
        gap: 5px;
        text-align: left;
    }

    .form-group label {
        font-weight: bold;
        color: #555;
    }

    .form-group input {
        padding: 10px;
        border: 1px solid #ddd;
        border-radius: 4px;
        font-size: 14px;
    }

    .form-group input:focus {
        outline: none;
        border-color: #4CAF50;
    }

    .submit-button {
        background-color: #4CAF50;
        color: white;
        border: none;
        padding: 12px;
        font-size: 16px;
        cursor: pointer;
        border-radius: 4px;
        margin-top: 10px;
        transition: background-color 0.3s;
    }

    .submit-button:hover {
        background-color: #45a049;
    }
</style>

</body>
</html>